{ Videokiosk
  screenconfig.pas

  Copyright (C) 2010 Malcolm Poole <mgpoole@users.sourceforge.net>

  This source is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 3 of the License, or (at your option)
  any later version.

  This code is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  details.

  A copy of the GNU General Public License is available on the World Wide Web
  at <http://www.gnu.org/copyleft/gpl.html>. You can also obtain it by writing
  to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  MA 02111-1307, USA.
}
unit screenconfig;

{$mode objfpc}{$H+}

interface

uses
  Classes, Sysutils, Fileutil, Lresources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, Spin, EditBtn, ExtDlgs, ExtCtrls, ComCtrls, Buttons, DOM, XMLWrite, XMLRead;

const
  DEFAULTCONFIG = 'config.xml';

type

  TButtonInfo = record
 //   Name: string;
    Top: integer;
    Left: integer;
    Width: integer;
    Height: integer;
    Color: TColor;
    Caption: string;
    Graphic: TFilename;
    Target: string;
    Action: byte;
  end;

  TLabelInfo = record
    Caption: string;
    Top: string[4];
    Left: string[4];
    FontName: string;
    FontSize: string[4];
  end;

  TScreenInfo = record
    Name: string;
    Color: integer;
    Graphic: TFilename;
    Buttons: array of TButtonInfo;
    Labels: array of TLabelInfo;
  end;


  { TConfigForm }

  TConfigForm = class ( Tform )
    Backgroundgroupbox: Tgroupbox;
    AboutButton: TButton;
    LogCheckBox: TCheckBox;
    Clicktostopplaycheckbox: Tcheckbox;
    LogFileNameEdit: TFileNameEdit;
    MPlayerFileNameEdit: TFileNameEdit;
    Label15: Tlabel;
    MplayerGroupBox: TGroupBox;
    OKBitBtn: TBitBtn;
    CancelBitBtn: TBitBtn;
    ApplyBitBtn: TBitBtn;
    ChangeFontButton: TButton;
    Buttonpanel: Tpanel;
    DefaultScreenCheckBox: TCheckBox;
    CursorCheckBox: TCheckBox;
    MiscOptionsGroupBox: TGroupBox;
    Label14: Tlabel;
    DefaultScreenSpinEdit: TSpinEdit;
    VideoBackgroundEdit: TFileNameEdit;
    Fontdialog1: Tfontdialog;
    Groupbox3: Tgroupbox;
    FontSizeLabel: TLabel;
    FontsampleLabel: TLabel;
    FontnameLabel: TLabel;
    FontStyleLabel: TLabel;
    Label6: Tlabel;
    MonitorDetailsButton: TButton;
    Buttonaddbutton: Tbutton;
    Buttoncaption: Tedit;
    Buttoncolor: Tcolorbutton;
    Buttondeletebutton: Tbutton;
    Buttongroupbox: Tgroupbox;
    Buttonheightspinedit: Tspinedit;
    Buttonimagefilename: Tfilenameedit;
    Buttonleftspinedit: Tspinedit;
    Buttonlist: Tlistbox;
    Buttontopspinedit: Tspinedit;
    Buttonwidthspinedit: Tspinedit;
    Groupbox2: Tgroupbox;
    Label1: Tlabel;
    Label10: Tlabel;
    Label11: Tlabel;
    Label12: Tlabel;
    ButtonColorLabel: TLabel;
    Label2: Tlabel;
    Label3: Tlabel;
    Label4: Tlabel;
    Label5: Tlabel;
    MonitorInfoLabel: TLabel;
    Label7: Tlabel;
    Label8: Tlabel;
    Label9: Tlabel;
    Labelgroupbox: Tgroupbox;
    Newscreenbutton: Tbutton;
    ConfigNotebook: TPageControl;
    Page1: TTabSheet;
    Options: TTabSheet;
    Previewimage: Timage;
    Previewpanel: Tpanel;
    Screencolorbutton: Tcolorbutton;
    Screendeletebutton: Tbutton;
    MenuGroupBox: TGroupBox;
    Screenheightspinedit: Tspinedit;
    Screenimagefilenameedit: Tfilenameedit;
    Screenlist: Tlistbox;
    Screennameedit: Tedit;
    Screenradiobutton: Tradiobutton;
    Screenselector: Tcombobox;
    Screenwidthspinedit: Tspinedit;
    Videofilename: Tfilenameedit;
    Videoradiobutton: Tradiobutton;
    procedure AboutButtonClick ( Sender: Tobject ) ;
    procedure Buttondeletebuttonclick ( Sender: Tobject ) ;
    procedure Logcheckboxchange ( Sender: Tobject ) ;
    procedure Mplayerfilenameeditchange ( Sender: Tobject ) ;
    procedure OKBitBtnClick ( Sender: Tobject ) ;
    procedure CancelBitBtnClick ( Sender: Tobject ) ;
    procedure ApplyBitBtnClick ( Sender: Tobject ) ;
    procedure ChangeFontButtonClick ( Sender: Tobject ) ;
    procedure ButtonAddButtonClick ( Sender: Tobject ) ;
    procedure Buttoneditenter ( Sender: Tobject ) ;
    procedure Buttoneditexit ( Sender: Tobject ) ;
    procedure Buttonimagefilenamechange ( Sender: Tobject ) ;
    procedure ButtonListBoxSelectionChange ( Sender: Tobject; User: Boolean ) ;
    procedure ButtonNameEditChange ( Sender: Tobject ) ;
    procedure Buttonwidthspineditchange ( Sender: Tobject ) ;
    procedure Colorbuttonchanged ( Sender: Tobject ) ;
    procedure Defaultscreencheckboxchange ( Sender: Tobject ) ;
    procedure Formdestroy ( Sender: Tobject ) ;
    procedure FormHide(Sender: TObject);
    procedure Monitordetailsbuttonclick ( Sender: Tobject ) ;
    procedure NewScreenButtonClick ( Sender: Tobject ) ;
    procedure Formcreate ( Sender: Tobject ) ;
    procedure Screendeletebuttonclick ( Sender: Tobject ) ;
    procedure Screenimagefilenameeditchange ( Sender: Tobject ) ;
    procedure Screenlistselectionchange ( Sender: Tobject; User: Boolean ) ;
    procedure Screennameeditchange ( Sender: Tobject ) ;
    procedure Screennameeditenter ( Sender: Tobject ) ;
    procedure Screennameeditexit ( Sender: Tobject ) ;
    procedure Screenselectorselect ( Sender: Tobject ) ;
    procedure Targetradiobuttonchange ( Sender: Tobject ) ;
    procedure Videofilenameacceptfilename ( Sender: Tobject; var Value: String
      ) ;
  private
    { private Declarations }
    fEntryValue: string;
    EditingButton: boolean;
    EditingScreen: boolean;
    fBufferImage: TBitmap;
    function WriteSettings: integer;
    function LoadSettings: integer;
    procedure ShowButton(buttonindex: integer);
    procedure SetScreen(screenindex: integer);
    function StoreButton: integer;
    function StoreScreen: integer;
    procedure DoPreview;
  public
    Screens: array of TScreenInfo;
    ShowSplash: Boolean;
    { public Declarations }
  end; 

var
  ConfigForm: TConfigForm;
  SettingsDir: string;

implementation

uses mainpanel, about;

procedure debugln(astring:string);
begin
  {$IFDEF LINUX}
  writeln(astring);
  {$ENDIF}
end;

function FontStyleToStr(style: TFontStyles): string;
var
  S: String;
  procedure AddStyle(s1: string);
  begin
    if S=''
       then S := s1
       else S := S + ',' +s1;
  end;
begin
  Result := '';
  S := '';
  if fsBold in style then AddStyle('bold');
  if fsItalic in style then AddStyle('italic');
  if fsUnderline in style then AddStyle('underline');
  if fsStrikeOut in style then AddStyle('strikeout');
  Result := S;
end;

{ TConfigForm }

procedure Tconfigform.NewScreenButtonClick ( Sender: Tobject ) ;
var
   ss: integer;
begin
  SetLength(Screens, Length(Screens)+1);
  with Screens[Length(Screens)-1] do
       begin
         Name := 'Screen ' + IntToStr(Length(Screens));
         Color := clSilver;
//         Width := IntToStr(Screen.Width);
//         Height := IntToStr(Screen.Height);
         Graphic := '';
       end;
  Screenlist.Items.Add(Screens[Length(Screens)-1].Name);
  Screenlist.ItemIndex := Screenlist.Count-1;
  ss := Screenselector.ItemIndex;
  ScreenSelector.Items.Add(Screens[Length(Screens)-1].Name);
  Screenselector.ItemIndex := ss;
  SetScreen(Screenlist.ItemIndex);
//  WriteSettings;
End;

procedure Tconfigform.ButtonAddButtonClick ( Sender: Tobject ) ;
var
   B: TButtonInfo;
begin
   SetLength(Screens[Screenlist.ItemIndex].Buttons, Length(Screens[Screenlist.ItemIndex].Buttons)+1);
   if Buttonlist.Count>0 then
      begin
        B := Screens[Screenlist.ItemIndex].Buttons[Buttonlist.Count-1];
          with Screens[Screenlist.ItemIndex].Buttons[Buttonlist.Count] do
            begin
              Caption := 'Button Label';
              Width := B.Width;
              Height := B.Height;
              Color := B.Color;
              Graphic := '';
              Action := 1;
              Target := '';
              if (B.Left + (B.Width + 50)*2)<Screen.Width
                 then begin
                        Left  := B.Left + B.Width + 50;
                        Top := B.Top;
                      end
              else begin
                     Left := Screens[Screenlist.ItemIndex].Buttons[0].Left;
                     Top := B.Top + B.Height + 50;
                   end;
              if Top + Height > Screen.Height
                 then MessageDlg('Button ' + IntToStr(Buttonlist.Count+1) + ' is below the lower edge of the screen', mtWarning, [mbOK], 0);
            end;
      end
   else
      with Screens[Screenlist.ItemIndex].Buttons[Buttonlist.Count] do
            begin
              Caption := 'Button Label';
              Top := 50;
              Left := 50;
              Width := 200;
              Height := 50;
              Color := clWhite;
              Graphic := '';
              Action := 1;
              Target := '';
            end;
   ButtonList.Items.Add('Button ' + IntToStr(Buttonlist.Count+1));
   ButtonList.ItemIndex := ButtonList.Count-1;
   ButtonListBoxselectionchange(nil, false);
   ButtonDeleteButton.Enabled := true;
End;

procedure Tconfigform.OKBitBtnClick ( Sender: Tobject ) ;
begin
  WriteSettings;
  ControlScreen.PrepareScreens('');
  Hide;
End;

procedure Tconfigform.Mplayerfilenameeditchange ( Sender: Tobject ) ;
begin
  ControlScreen.VideoPlayer.MPlayerPath := MPlayerFileNameEdit.FileName;
End;

procedure Tconfigform.AboutButtonClick ( Sender: Tobject ) ;
begin
  if not Assigned(AboutForm) then exit;
  AboutForm.ShowModal;
End;

procedure Tconfigform.Buttondeletebuttonclick ( Sender: Tobject ) ;
var
  X: Longint;
  I: Longint;
begin
  i := Buttonlist.ItemIndex;
  for x := i to Buttonlist.Count-2 do
      begin
        Screens[Screenlist.ItemIndex].Buttons[x] := Screens[Screenlist.ItemIndex].Buttons[x+1];
      end;
  Buttonlist.Items.Delete(i);
  SetLength(Screens[Screenlist.ItemIndex].Buttons, Buttonlist.Count);
  if i>Buttonlist.Count-1
     then if i>0 then Dec(i);
  Buttonlist.ItemIndex := i;
  ButtonListBoxSelectionChange(nil, false);
  Buttondeletebutton.Enabled := Buttonlist.Count>1;
End;

procedure Tconfigform.Logcheckboxchange ( Sender: Tobject ) ;
begin
  LogFileNameEdit.Enabled := LogCheckBox.Checked;
End;

procedure Tconfigform.CancelBitBtnClick ( Sender: Tobject ) ;
begin
  Hide;
End;

procedure Tconfigform.ApplyBitBtnClick ( Sender: Tobject ) ;
begin
  WriteSettings;
  ControlScreen.PrepareScreens('');
End;

procedure Tconfigform.ChangeFontButtonClick ( Sender: Tobject ) ;
begin
  if Fontdialog1.Execute then
     begin
       FontsampleLabel.Font := Fontdialog1.Font;
       FontnameLabel.Caption := Fontdialog1.Font.Name;
       FontStyleLabel.Caption := FontStyleToStr( Fontdialog1.Font.Style );
       FontSizeLabel.Caption := 'Size: ' +IntToStr(Fontdialog1.Font.Size);
     end;
End;

procedure Tconfigform.Buttoneditenter ( Sender: Tobject ) ;
begin
  EditingButton := true;
  if Sender is TCustomEdit
     then fEntryValue := TCustomEdit(Sender).Text
  else if Sender is TComboBox
     then fEntryValue := TComboBox(Sender).Text;
End;

procedure Tconfigform.Buttoneditexit ( Sender: Tobject ) ;
begin
//  debugln('buttoneditexit');
  EditingButton := false;
  if Sender is TCustomEdit
     then if fEntryValue<>TCustomEdit(Sender).Text
           then StoreButton;
End;

procedure Tconfigform.Buttonimagefilenamechange ( Sender: Tobject ) ;
var
   TempImage: TImage;
begin
    if FileExistsUTF8(Buttonimagefilename.FileName) then
        begin
        Screens[Screenlist.ItemIndex].Buttons[Buttonlist.ItemIndex].Graphic := Buttonimagefilename.FileName;
        TempImage := TImage.Create(nil);
        try
          TempImage.Picture.LoadFromFile(Buttonimagefilename.FileName);
          Buttonheightspinedit.Value := TempImage.Picture.Height+10;
          Screens[Screenlist.ItemIndex].Buttons[Buttonlist.ItemIndex].Height := TempImage.Picture.Height+10;
          Buttonwidthspinedit.Value := TempImage.Picture.Width+10;
          Screens[Screenlist.ItemIndex].Buttons[Buttonlist.ItemIndex].Width := TempImage.Picture.Width+10;
        finally
          TempImage.Free;
        end;
        end;
End;

procedure Tconfigform.ButtonListBoxSelectionChange ( Sender: Tobject; User: Boolean
  ) ;
begin
//  debugln('button select change');
  ShowButton(ButtonList.ItemIndex);
  DoPreview;
End;

procedure Tconfigform.ButtonNameEditChange ( Sender: Tobject ) ;
begin
 // ButtonList.Items[ButtonList.ItemIndex] := ButtonNameEdit.Text;
End;

procedure Tconfigform.Buttonwidthspineditchange ( Sender: Tobject ) ;
begin
  if EditingButton then
     begin
       StoreButton;
       DoPreview;
     end;
End;

procedure Tconfigform.Colorbuttonchanged ( Sender: Tobject ) ;
begin
  if Sender=ButtonColor
     then StoreButton
  else if Sender=ScreenColorButton
     then StoreScreen;;
End;

procedure Tconfigform.Defaultscreencheckboxchange ( Sender: Tobject ) ;
begin
  DefaultScreenSpinEdit.Enabled := DefaultScreenCheckBox.Checked;
End;

procedure Tconfigform.Formdestroy ( Sender: Tobject ) ;
begin
  if fBufferImage <> nil then fBufferImage.Free;
End;

procedure TConfigForm.FormHide(Sender: TObject);
begin
  ControlScreen.WindowState := wsMaximized;
  ControlScreen.BorderStyle:=bsNone;
  if CursorCheckBox.Checked then Screen.Cursor:=crNone;
end;

procedure Tconfigform.Monitordetailsbuttonclick ( Sender: Tobject ) ;
var
  X: Integer;
  Monitorinfo: String;
begin
  Monitorinfo := '';
  for x := 0 to Screen.MonitorCount-1 do
      begin
        MonitorInfo := Monitorinfo + 'Monitor ' + IntToStr(x+1) + #10
                      + 'Left: ' + IntTostr(Screen.Monitors[x].Left)
                      + '  Top: ' + IntTostr(Screen.Monitors[x].Top)+#10
                      + 'Width: ' + IntTostr(Screen.Monitors[x].Width)
                      + '  Height: ' + IntTostr(Screen.Monitors[x].Height)+#10#10;
      end;
  ShowMessage(Monitorinfo);
End;

procedure Tconfigform.Formcreate ( Sender: Tobject ) ;
var
  S: Integer;
  Userhome: String;
begin
  ShowSplash := true;
  {$IFDEF WIN32}
  MPlayerFileNameEdit.Filename:='C:\Program Files\SMPlayer\mplayer\mplayer.exe';
  if not FileExistsUTF8(MPlayerFileNameEdit.Filename)
     then MPlayerFileNameEdit.Filename:='C:\Program Files\MPlayer\mplayer.exe';
  SettingsDir := GetAppConfigDirUTF8(true);
  if not DirectoryExistsUTF8(SettingsDir)
     then mkdir(SettingsDir);
  LogFileNameEdit.Filename := 'C:\videokiosk.log';
  {$ENDIF}
  {$IFDEF LINUX}
  MPlayerFileNameEdit.FileName:='mplayer';
    UserHome := SysUtils.GetEnvironmentVariable('HOME');
  if FileExistsUTF8(UserHome + '/.config')
     then SettingsDir := UserHome + '/.config/videokiosk/'
     else SettingsDir := UserHome + '/.videokiosk/';
  if not FileExistsUTF8(SettingsDir)
     then mkdir(SettingsDir);
  LogFileNameEdit.Filename := 'videokiosk.log';
{$ENDIF}
  if FileExistsUTF8(SettingsDir + DEFAULTCONFIG)
     then LoadSettings;
  ControlScreen.VideoPlayer.MPlayerPath := MPlayerFileNameEdit.FileName;
  if Length(Screens)< 1 then
     begin
     SetLength(Screens, 1);
     with Screens[0] do
       begin
         Name:= 'Screen 1';
//         Width:= IntToStr( Screen.Width );
//         Height:= IntToStr( Screen.Height );
         Color:= clSilver;
         Graphic:= '';
         SetLength(Buttons, 0);
       end;
     end;
  Screenlist.Clear;
  for s := 0 to Length(Screens)-1 do
      Screenlist.items.Add(Screens[s].Name);
  ScreenList.ItemIndex := 0;
  SetScreen(Screenlist.ItemIndex);
  ScreenSelector.Items.Assign(Screenlist.Items);
  if Screenselector.Items.Count> 0
     then Screenselector.ItemIndex := 0;
  {$IFDEF WIN32}
  ButtonColorLabel.Visible := false;
  Buttoncolor.Visible := false;
  {$ENDIF}
End;

procedure Tconfigform.Screendeletebuttonclick ( Sender: Tobject ) ;
var
  X: Longint;
  I: Longint;
begin
  i := Screenlist.ItemIndex;
  for x := i to Screenlist.Count-2 do
      begin
        Screens[x] := Screens[x+1];
      end;
  Screenlist.Items.Delete(i);
  SetLength(Screens, Screenlist.Count);
  Screenselector.Items := Screenlist.Items;
  if i>Screenlist.Count-1
     then if i>0 then Dec(i);
  Screenlist.ItemIndex := i;
  Screenlistselectionchange(nil, false);
  Screendeletebutton.Enabled := Screenlist.Count>1;
End;

procedure Tconfigform.Screenimagefilenameeditchange ( Sender: Tobject ) ;
begin
  if FileExistsUTF8(Screenimagefilenameedit.FileName) then
        begin
        Screens[Screenlist.ItemIndex].Graphic := Screenimagefilenameedit.FileName;
        Screenlistselectionchange(nil, false);
        end;
End;

procedure Tconfigform.Screenlistselectionchange ( Sender: Tobject;
  User: Boolean ) ;
begin
  SetScreen(Screenlist.ItemIndex);
End;

procedure Tconfigform.Screennameeditchange ( Sender: Tobject ) ;
begin
  if EditingScreen then
     begin
      Screenlist.Items[Screenlist.ItemIndex] := ScreenNameEdit.Text;
      Screens[Screenlist.ItemIndex].Name := ScreenNameEdit.Text;
     end;
End;

procedure Tconfigform.Screennameeditenter ( Sender: Tobject ) ;
begin
  EditingScreen := true;
End;

procedure Tconfigform.Screennameeditexit ( Sender: Tobject ) ;
begin
  if EditingScreen then StoreScreen;
  EditingScreen := false;
End;

procedure Tconfigform.Screenselectorselect ( Sender: Tobject ) ;
begin
  StoreButton;
End;

procedure Tconfigform.Targetradiobuttonchange ( Sender: Tobject ) ;
begin
  ScreenSelector.Enabled := ScreenRadioButton.Checked;
  VideoFileName.Enabled := VideoRadioButton.Checked;
  StoreButton;
End;

procedure Tconfigform.Videofilenameacceptfilename ( Sender: Tobject;
  var Value: String ) ;
begin
  StoreButton;
End;

function Tconfigform.Writesettings: Integer;
var
  xdoc: TXMLDocument;                                  // variable to document
  RootNode, parentNode: TDOMNode;                    // variable to nodes
  Childnode: Tdomelement;
  Btn: TButtonInfo;
  S: Integer;
  B: Integer;
begin
  //create a document
  xdoc := TXMLDocument.create;

  //create a root node
  RootNode := xdoc.CreateElement('videokiosk');

  Xdoc.Appendchild(RootNode);                           // save root node
  RootNode:= xdoc.DocumentElement;

  parentNode := xdoc.CreateElement('startup');
  TDOMElement(parentNode).SetAttribute('splashscreen', BoolToStr(ShowSplash));
  RootNode.Appendchild(parentNode);
  if Fontdialog1.Font.Name<>'default' then
     begin
      parentNode := xdoc.CreateElement('buttonfont');
      TDOMElement(parentNode).SetAttribute('name', Fontdialog1.Font.Name);
      TDOMElement(parentNode).SetAttribute('size', IntToStr(Fontdialog1.Font.Size));
      TDOMElement(parentNode).SetAttribute('bold', BoolToStr(fsBold in Fontdialog1.Font.Style));
      TDOMElement(parentNode).SetAttribute('italic', BoolToStr(fsItalic in Fontdialog1.Font.Style));
      TDOMElement(parentNode).SetAttribute('underline', BoolToStr(fsUnderline in Fontdialog1.Font.Style));
      TDOMElement(parentNode).SetAttribute('strikeout', BoolToStr(fsStrikeOut in Fontdialog1.Font.Style));
      TDOMElement(parentNode).SetAttribute('color', IntToStr(Fontdialog1.Font.Color));
      RootNode.AppendChild(parentNode);
     end;
  if FileExistsUTF8(VideoBackgroundEdit.FileName) then
     begin
      parentNode := xdoc.CreateElement('videobackground');
      TDOMElement(parentNode).SetAttribute('value', VideoBackgroundEdit.Text);
      RootNode.Appendchild(parentNode);
     end;
  parentNode := xdoc.CreateElement('controlcursor');
  TDOMElement(parentNode).SetAttribute('visible', BoolToStr(CursorCheckBox.Checked));
  RootNode.Appendchild(parentNode);
  parentNode := xdoc.CreateElement('resetdelay');
  TDOMElement(parentNode).SetAttribute('enabled', BoolToStr(DefaultScreenCheckBox.Checked));
  TDOMElement(parentNode).SetAttribute('delay', IntToStr(DefaultScreenSpinEdit.Value));
  RootNode.Appendchild(parentNode);
  parentNode := xdoc.CreateElement('mplayer');
  TDOMElement(parentNode).SetAttribute('location', MPlayerFileNameEdit.FileName);
  RootNode.Appendchild(parentNode);
  parentNode := xdoc.CreateElement('cancelplayback');
  TDOMElement(parentNode).SetAttribute('enabled', BoolToStr(ClickToStopPlayCheckBox.Checked));
  RootNode.Appendchild(parentNode);
  parentNode := xdoc.CreateElement('activitylog');
  TDOMElement(parentNode).SetAttribute('enabled', BoolToStr(LogCheckBox.Checked));
  TDOMElement(parentNode).SetAttribute('filename', LogFileNameEdit.FileName);
  RootNode.Appendchild(parentNode);

  for s := 0 to Length(Screens)-1 do
      begin
        parentNode := xdoc.CreateElement('screen');
        TDOMElement(parentNode).SetAttribute('name', TScreenInfo(Screens[s]).Name);
  //      TDOMElement(parentNode).SetAttribute('width', TScreenInfo(Screens[s]).Width);
  //      TDOMElement(parentNode).SetAttribute('height', TScreenInfo(Screens[s]).Height);
        TDOMElement(parentNode).SetAttribute('color', IntToStr(TScreenInfo(Screens[s]).Color));
        TDOMElement(parentNode).SetAttribute('graphic', TScreenInfo(Screens[s]).Graphic);

        RootNode.Appendchild(parentNode);                          // save parent node

        for b := 0 to Length(TScreenInfo(Screens[s]).Buttons)-1 do
            begin
              Btn := TScreenInfo(Screens[s]).Buttons[b];
              childNode := xdoc.CreateElement('button');                // create a child node
              TDOMElement(childNode).SetAttribute('caption', Btn.Caption);     // create atributes
              TDOMElement(childNode).SetAttribute('top', IntToStr(Btn.Top));  // create atributes
              TDOMElement(childNode).SetAttribute('left', IntToStr(Btn.Left)); //te atributes
              TDOMElement(childNode).SetAttribute('width', IntToStr(Btn.Width));     // create atributes
              TDOMElement(childNode).SetAttribute('height', IntToStr(Btn.Height));  // create atributes
              TDOMElement(childNode).SetAttribute('color', IntToStr(Btn.Color)); // create atributes
              TDOMElement(childNode).SetAttribute('graphic', Btn.Graphic);     // create atributes
              TDOMElement(childNode).SetAttribute('action', IntToStr(Btn.Action));     // create atributes
              TDOMElement(childNode).SetAttribute('target', Btn.Target);     // create atributes
              ParentNode.AppendChild(Childnode);       // insert child node in respective parent node
            end;
      end;
  writeXMLFile(xDoc, SettingsDir + DEFAULTCONFIG);     // write to XML
  Xdoc.free;                                          // free memory
end;

function Tconfigform.Loadsettings: Integer;
var
  Doc:      TXMLDocument;
  sectionNode: TDOMnode;
  buttonNode: TDOMnode;
  S: Integer;
  B: Integer;
 begin
  // Read in xml file from disk
   S := 0;
  ReadXMLFile(Doc, SettingsDir + DEFAULTCONFIG);
  if Doc.DocumentElement <> nil then
     sectionNode := Doc.DocumentElement.FirstChild;
  repeat
    if sectionNode.NodeName='startup' then
         ShowSplash := StrToBool(TDOMElement(sectionNode).GetAttribute('splashscreen'));
    if sectionNode.NodeName='buttonfont' then
       begin
         Fontdialog1.Font.Name := TDOMElement(sectionNode).GetAttribute('name');
         Fontdialog1.Font.Size := StrToInt(TDOMElement(sectionNode).GetAttribute('size'));
         Fontdialog1.Font.Color := StrToInt(TDOMElement(sectionNode).GetAttribute('color'));
         if StrToBool(TDOMElement(sectionNode).GetAttribute('italic'))
            then Fontdialog1.Font.Style := Fontdialog1.Font.Style+[fsItalic];
         if StrToBool(TDOMElement(sectionNode).GetAttribute('bold'))
            then Fontdialog1.Font.Style := Fontdialog1.Font.Style+[fsBold];
         if StrToBool(TDOMElement(sectionNode).GetAttribute('underline'))
            then Fontdialog1.Font.Style := Fontdialog1.Font.Style+[fsUnderline];
         if StrToBool(TDOMElement(sectionNode).GetAttribute('strikeout'))
            then Fontdialog1.Font.Style := Fontdialog1.Font.Style+[fsStrikeOut];
         FontsampleLabel.Font := Fontdialog1.Font;
         FontnameLabel.Caption := Fontdialog1.Font.Name;
         FontStyleLabel.Caption := FontStyleToStr( Fontdialog1.Font.Style );
         FontSizeLabel.Caption := 'Size: ' +IntToStr(Fontdialog1.Font.Size);
       end;
    if sectionNode.NodeName='videobackground' then
       VideoBackgroundEdit.FileName := TDOMElement(sectionNode).GetAttribute('value');
    if sectionNode.NodeName='controlcursor' then
       CursorCheckBox.Checked := StrToBool(TDOMElement(sectionNode).GetAttribute('visible'));
    if sectionNode.NodeName='resetdelay' then
       begin
         DefaultScreenCheckBox.Checked := StrToBool(TDOMElement(sectionNode).GetAttribute('enabled'));
         DefaultScreenSpinEdit.Value := StrToInt(TDOMElement(sectionNode).GetAttribute('delay'));
       end;
    if sectionNode.NodeName='mplayer' then
       MPlayerFileNameEdit.FileName := TDOMElement(sectionNode).GetAttribute('location');
    if sectionNode.NodeName='cancelplayback' then
       ClickToStopPlayCheckBox.Checked := StrToBool(TDOMElement(sectionNode).GetAttribute('enabled'));
    if sectionNode.NodeName='activitylog' then
       begin
         LogCheckBox.Checked := StrToBool(TDOMElement(sectionNode).GetAttribute('enabled'));
         LogFileNameEdit.FileName := TDOMElement(sectionNode).GetAttribute('filename');
       end;
    if sectionNode.NodeName='screen' then
       begin
         Setlength(Screens, s+1);
         with Screens[s] do
              begin
                Name := TDOMElement(sectionNode).GetAttribute('name');
    //            Width := TDOMElement(sectionNode).GetAttribute('width');
    //            Height := TDOMElement(sectionNode).GetAttribute('height');
                Color := StrToInt(TDOMElement(sectionNode).GetAttribute('color'));
                Graphic := TDOMElement(sectionNode).GetAttribute('graphic');
                buttonNode := sectionNode.FirstChild;
                b := 0;
                repeat
                    begin
                      SetLength(Screens[s].Buttons, b+1);
                      with Screens[s].Buttons[b] do
                           begin
                           // Name := buttonNode.FirstChild.NodeValue;
                            Width := StrToInt(TDOMElement(buttonNode).GetAttribute('width'));
                            Height := StrToInt(TDOMElement(buttonNode).GetAttribute('height'));
                            Color := StrToInt(TDOMElement(buttonNode).GetAttribute('color'));
                            Top := StrToInt(TDOMElement(buttonNode).GetAttribute('top'));
                            Left := StrToInt(TDOMElement(buttonNode).GetAttribute('left'));
                            Graphic := TDOMElement(buttonNode).GetAttribute('graphic');
                            Action := StrToInt(TDOMElement(buttonNode).GetAttribute('action'));
                            Target := TDOMElement(buttonNode).GetAttribute('target');
                            Caption := TDOMElement(buttonNode).GetAttribute('caption');
                            buttonNode := buttonNode.NextSibling;
                           end;
                      inc(b);
                    end;
                until not Assigned(buttonNode);
              end;
         Inc(s);
       end;
    sectionNode := sectionNode.NextSibling;
  until not Assigned(sectionNode);
  Doc.Free;
  Screendeletebutton.Enabled := Length(Screens)>1;
end;

procedure Tconfigform.Showbutton ( Buttonindex: Integer ) ;
var
  b: TButtonInfo;
  T: integer;
begin
//  debugln('showbutton');
  B := TScreenInfo(Screens[Screenlist.ItemIndex]).Buttons[Buttonindex];
//  ButtonNameEdit.Text := B.Name;
  ButtonCaption.Text := B.Caption;
  ButtonTopSpinEdit.Value := B.Top;
  ButtonLeftSpinEdit.Value := B.Left;
  ButtonWidthSpinEdit.Value := B.Width;
  ButtonHeightSpinEdit.Value := B.Height;
  ButtonImageFileName.FileName := B.Graphic;
  ButtonColor.ButtonColor := B.Color;
  ScreenSelector.ItemIndex := 0;
//  debugln('Action is: ' + B.Action);
  if B.Action = 0 then
     begin
       ScreenRadioButton.Checked := true;
       T := 0;
       TryStrToInt(B.Target, T);
       if T<0 then T := 0;
       ScreenSelector.ItemIndex := T;
     end
  else
     begin
       VideoRadioButton.Checked := true;
       VideoFileName.FileName := B.Target;
     end;
  DoPreview;
end;

procedure Tconfigform.Setscreen ( Screenindex: Integer ) ;
var
  b : integer;
  tempimage:TImage;
begin
  with Screens[Screenindex] do
       begin
         ScreenNameEdit.Text := Name;
//         ScreenWidthSpinEdit.Value := StrToInt(Width);
//         ScreenHeightSpinEdit.Value := StrToInt(Height);
         ScreenImageFileNameEdit.FileName := Graphic;
         if fBufferImage <> nil then
            begin
              fBufferImage.Free;
              fBufferImage := nil;
            end;
         fBufferImage := TBitmap.Create;
         fBufferImage.Width := PreviewPanel.Width;
         fBufferImage.Height := PreviewPanel.Height;
         tempimage := TImage.Create(nil);
         try
           if Graphic<>'' then tempimage.Picture.LoadFromFile(Graphic);
           fBufferImage.Canvas.StretchDraw(PreviewPanel.ClientRect,tempimage.Picture.Bitmap);
         finally
           tempimage.Free;
         end;


         ScreenColorButton.ButtonColor := Color;
         ButtonList.Clear;      //TODO: Clear contents of button information
         for B := 0 to Length(Buttons)-1 do
             with Buttons[B] do
                  begin
                    ButtonList.Items.Add('Button ' + IntToStr(B+1));
                  end;
         if ButtonList.Count > 0 then
            begin
              ButtonList.ItemIndex := 0;
              ShowButton(0);
            end;
       end;
  Buttondeletebutton.Enabled := Buttonlist.Count>1;
end;

function Tconfigform.Storebutton: Integer;
begin
  //debugln('storebuttons');
  with TButtonInfo(Screens[Screenlist.ItemIndex].Buttons[ButtonList.ItemIndex]) do
       begin
         //Name := ButtonNameEdit.Text;
         Caption := ButtonCaption.Text;
         Top := ButtonTopSpinEdit.Value;
         Left := ButtonLeftSpinEdit.Value;
         Width := ButtonWidthSpinEdit.Value;
         Graphic := ButtonImageFileName.Text;
         Color := ButtonColor.ButtonColor;
         if ScreenRadioButton.Checked
            then begin Action := 0; Target := IntToStr(ScreenSelector.ItemIndex); end
            else begin Action := 1; Target := VideoFileName.Text; end;

       end;
end;

function Tconfigform.Storescreen: Integer;
begin
 // debugln('storescreen');
  with Screens[Screenlist.ItemIndex] do
       begin
         Name := ScreenNameEdit.Text;
         Graphic := ScreenImageFileNameEdit.FileName;
         Color := ScreenColorButton.ButtonColor;
       end;
end;

procedure Tconfigform.Dopreview;
var
  B: Integer;
  ButtonRect: TRect;
  Previewscale: Extended;
begin
  PreviewScale := PreviewPanel.Width/Screen.Width;
  PreviewPanel.Height := Trunc(Screen.Height * Previewscale);
  if Screens[Screenlist.ItemIndex].Graphic <> ''
     then PreviewImage.Picture.Bitmap := fBufferImage
     else
        with PreviewImage.Picture.Bitmap do
        begin
       Canvas.Brush.Color := Screens[Screenlist.ItemIndex].Color;
       Canvas.Rectangle(PreviewPanel.ClientRect);
     end;
  for b := 0 to Length(Screens[Screenlist.ItemIndex].Buttons)-1 do
       begin
         if b=ButtonList.ItemIndex
            then PreviewImage.Picture.Bitmap.Canvas.Pen.Color := clBlack
         else   PreviewImage.Picture.Bitmap.Canvas.Pen.Color := clSilver;
         PreviewImage.Picture.Bitmap.Canvas.Brush.Color := Screens[Screenlist.ItemIndex].Buttons[b].Color;
         ButtonRect.Left := Trunc(Screens[Screenlist.ItemIndex].Buttons[b].Left * Previewscale);
         ButtonRect.Top := Trunc(Screens[Screenlist.ItemIndex].Buttons[b].Top  * Previewscale);
         ButtonRect.Bottom := Trunc(ButtonRect.Top+Screens[Screenlist.ItemIndex].Buttons[b].Height  * Previewscale);
         ButtonRect.Right := Trunc(ButtonRect.Left+Screens[Screenlist.ItemIndex].Buttons[b].Width  * Previewscale);
         PreviewImage.Picture.Bitmap.Canvas.Rectangle(ButtonRect);
       end;
  //PreviewImage.Picture.Bitmap.Assign(fPreviewImage.Picture.Bitmap);
end;


initialization
  {$I screenconfig.lrs}

end.

